﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using Office = Microsoft.Office.Core;

using System.Data;
using Word = Microsoft.Office.Interop.Word;
using Microsoft.Office.Tools.Word.Extensions; // for VSTOObject


using NLog;
namespace OpenDoPE_Wed
{
    [ComVisible(true)]
    public class Ribbon : Office.IRibbonExtensibility
    {
        /* This ribbon is (largely) stateless.
        // The active document contains the state.
         * 
         * The intent is that a result overview document,
         * and its group of instance documents,
         * behave as a connected group (ie with
         * consistent next|previous behaviour).
         * 
         * This should be true for each overview|instance
         * group.
         * 
         */

        static private Office.IRibbonUI ribbon;
        public static Office.IRibbonUI getRibbon()
        {


            return ribbon;
        }

        //private static Microsoft.Office.Tools.CustomTaskPane ctp;

        public static void myInvalidate()
        {
            //ctp = findCustomTaskPane();
            Ribbon.ribbon.Invalidate();
        }


        /*
         * IRibbonUI behaves like a singleton (though nowhere does
         * the MSDN doc actually say this?)
         * 
         * Observation:  Activating a Window calls get on text box 
         * (if Word determines that is necessary), but stops short 
         * of invalidating the ribbon, (since that would set new values in
         * the menus and by observation, the menu in each window is different).
         * 
         * Clicked on a result in results overview; Observed to change 
         * text box in another window. (But it will change back when 
         * i activate that window)
         */

        static Logger log = LogManager.GetLogger("OpenDoPE_Wed");

        public Ribbon()
        {
            log.Debug("Ribbon constructed.");
        }

/*
        public System.Drawing.Bitmap LoadImage(string imageName)
        {
            Assembly assembly = Assembly.GetExecutingAssembly();
            Stream stream = assembly.GetManifestResourceStream("com.plutext.search.main.google_desktop_facicon.bmp");

            //string[] names = assembly.GetManifestResourceNames();
            //foreach (string name in names)
            //    log.Debug(name);

            return new System.Drawing.Bitmap(stream);
        }
        */


        #region IRibbonExtensibility Members

        public string GetCustomUI(string ribbonID)
        {
            return GetResourceText("OpenDoPE_Wed.Ribbon.xml");
        }

        #endregion

        #region Ribbon Callbacks
        //Create callback methods here. For more information about adding callback methods, select the Ribbon XML item in Solution Explorer and then press F1

        // See http://msdn.microsoft.com/en-us/library/aa722523.aspx for signatures

        public void Ribbon_Load(Office.IRibbonUI ribbonUI)
        {
            Ribbon.ribbon = ribbonUI;
        }


        /// <summary>
        /// Call this in order to add custom xml parts to a document.
        /// Once they have been added, it should be greyed out.
        /// </summary>
        /// <param name="control"></param>
        public void buttonAddDoPE_Click(Office.IRibbonControl control)
        {
            FormInitialSetup form = new FormInitialSetup();
            form.ShowDialog();

            myInvalidate(); 


            /* String xml = System.IO.File.ReadAllText(@"C:\Users\jharrop\workspace\docx4j_1\sample-docs\aaa Document.xml");
            object missing = System.Reflection.Missing.Value;
            Globals.ThisAddIn.Application.Selection.InsertXML(xml, ref missing);
             */

        }

        public Boolean IsAddDoPEEnabled(Office.IRibbonControl control)
        {
            // When the user opens an existing document, we create the
            // CTP iff our parts are present.  

            // So if there is a CTP for this docx, disable the button;
            // otherwise, enable it
            //if (findCustomTaskPane() == null) return true;
            //else return false;

            // But if the ctp isn't there for some reason,
            // but OpenDoPE parts are present
            // we don't want the user pressing this button.
            // So:
            return !openDoPEPartsPresent();
        }

        private bool openDoPEPartsPresent()
        {
            foreach (Office.CustomXMLPart cp in Globals.ThisAddIn.Application.ActiveDocument.CustomXMLParts)
            {
                if (cp.NamespaceURI.Equals(Namespaces.XPATHS))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// If user clicks close [x] on a task pane, that sets its visible=false.
        /// This sets visible=true again.
        /// </summary>
        /// <param name="control"></param>
        public void buttonShowCTP_Click(Office.IRibbonControl control)
        {
            // Could use visibility changed event to update button

            Microsoft.Office.Tools.CustomTaskPane ctp = findCustomTaskPane();

            if (ctp == null)
            {
                // This shouldn't happen.  If it does, we need to recreate
                log.Warn("CTP missing .. attempting to recreate.");
                ctp = Globals.ThisAddIn.createCTP(Globals.ThisAddIn.Application.ActiveDocument);
            }

            if (ctp.Visible)
            {
                Mbox.ShowSimpleMsgBoxInfo("I reckon its visible already");
                return;
            }

            ctp.Visible = true;
        }

        public Boolean IsShowCTPEnabled(Office.IRibbonControl control)
        {
            Microsoft.Office.Tools.CustomTaskPane ctp = findCustomTaskPane();
            if (ctp == null) 
            {
                return openDoPEPartsPresent();
            }

            if (ctp.Visible)
            {
                return false;
            }
            else { return true; }
        }

        private static Microsoft.Office.Tools.CustomTaskPane findCustomTaskPane() {

            Microsoft.Office.Tools.Word.Document extendedDocument
                = Globals.ThisAddIn.Application.ActiveDocument.GetVstoObject(Globals.Factory);

            if (extendedDocument.Tag != null
                && extendedDocument.Tag is Microsoft.Office.Tools.CustomTaskPane)
            {
                log.Debug("found ctp");
                return (Microsoft.Office.Tools.CustomTaskPane)extendedDocument.Tag;
            }
            else
            {
                log.Debug("no ctp attached to this docx");
                return null;
            }
        }

        //private static Microsoft.Office.Tools.CustomTaskPane findCustomTaskPane()
        //{
        //    Word.Window wn = Globals.ThisAddIn.Application.ActiveWindow;

        //    WedTaskPane wedTaskPane = null;


        //    foreach (Microsoft.Office.Tools.CustomTaskPane ctpx in Globals.ThisAddIn.CustomTaskPanes)
        //    {

        //        if (((Word.Window)ctpx.Window) == wn
        //            && ctpx.Control is WedTaskPane)
        //        {
        //            log.Debug("found ctp");

        //            wedTaskPane = (WedTaskPane)ctpx.Control;

        //            // Verify, since if a doc with a ctp attached is closed,
        //            // the ctp is moved to another doc!
        //            if (!wedTaskPane.windowCaption.Equals("OpenDoPE " + wn.Caption))
        //            {
        //                log.Debug("but its obsolete...");
        //                continue;
        //            }

        //            return ctpx;
        //        }
        //        else
        //        {
        //            //log.Debug("..not ctp window");
        //        }
        //    }
        //    return null;
        //}


        public void buttonShowDocumentXml_Click(Office.IRibbonControl control)
        {
            WedTaskPane wtp = Globals.ThisAddIn.getTaskPane();
            if (wtp == null)
            {
                Mbox.ShowSimpleMsgBoxInfo("You can't do this because your docx doesn't contain OpenDoPE parts");
                return;
            }

            wtp.showDocumentInXmlEditor();
        }

/*
        public void buttonShowXPathsPart_Click(Office.IRibbonControl control)
        {
            Mbox.ShowSimpleMsgBoxInfo("This will display your XPath's part");
        } */

        public void buttonXPathsFixDupes_Click(Office.IRibbonControl control)
        {

            WedTaskPane wtp = Globals.ThisAddIn.getTaskPane();
            if (wtp == null)
            {
                Mbox.ShowSimpleMsgBoxInfo("Document doesn't contain OpenDoPE parts");
                return;
            }

            XPathPartUtils.fixDupeIDs(wtp.xpathsPart);
        }

        public void buttonInjectMacro_Click(Office.IRibbonControl control)
        {
            MacroManager.injectMacro();
        }

        public Boolean isInjectMacroEnabled(Office.IRibbonControl control)
        {
            // TODO, grey out once macro has been added
            if (findCustomTaskPane() == null) return false;
            else return true;
        }

// -------------------------

        //public Boolean isToggleAllInParagraphEnabled(Office.IRibbonControl control)
        //{
        //}


        /**********************************************************
         *     Help, Feedback etc
         **********************************************************/

/*
        public void buttonHelp_Click(Office.IRibbonControl control)
        {
            string dir = Assembly.GetExecutingAssembly().CodeBase;
            log.Debug("Locating help file relative to " + dir);
            dir = dir.Replace(@"file:///", string.Empty);
            int lastPost = dir.LastIndexOf("/");
            dir = dir.Substring(0, lastPost) + "/help/";
            dir = dir.Replace("/", "\\");

            object fileName = dir + "Results Springboard Help.docx";

            try
            {
                object omissing = System.Reflection.Missing.Value;
                object addToRecentFilesObj = false;

                Word.Document resultDoc = Globals.ThisAddIn.Application.Documents.Open(ref fileName, ref omissing, ref omissing, ref addToRecentFilesObj, ref omissing,
                                                 ref omissing, ref omissing, ref omissing, ref omissing, ref omissing, ref omissing,
                                                 ref omissing, ref omissing, ref omissing, ref omissing, ref omissing);
                resultDoc.Activate();
            }
            catch (Exception e)
            {
                System.Windows.Forms.MessageBox.Show("Unable to open local Help file.  Please visit our help online at www.plutext.com");
                log.Error("Unable to open '" + fileName);
                log.Error(e.Message);
                return;
            }


        }

        public void buttonFeedback_Click(Office.IRibbonControl control)
        {
            if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
            {
                System.Windows.Forms.MessageBox.Show("You don't appear to have an internet connection right now.  Please try again later.");
                return;
            }

            FormFeedback ff = new FormFeedback();
            ff.ShowDialog();
        }

*/

        /* To have just a simple next button, which turns into a menu
         * if held for long enough, see http://www.keyongtech.com/569303-how-to-tell-how-long
         * 
         * Essentially, you use System.Windows.Forms.MouseEventHandler
         * 
         * Would need to position the menu properly.
         */

        #endregion

        #region Helpers

        private static string GetResourceText(string resourceName)
        {
            log.Debug("Fetching resource: " + resourceName);
            Assembly asm = Assembly.GetExecutingAssembly();
            string[] resourceNames = asm.GetManifestResourceNames();
            for (int i = 0; i < resourceNames.Length; ++i)
            {
                if (string.Compare(resourceName, resourceNames[i], StringComparison.OrdinalIgnoreCase) == 0)
                {
                    using (System.IO.StreamReader resourceReader = new System.IO.StreamReader(asm.GetManifestResourceStream(resourceNames[i])))
                    {
                        if (resourceReader != null)
                        {
                            return resourceReader.ReadToEnd();
                        }
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// Need this if SearchProviders.isGoogleDesktopSearchAvailable
        ///        || SearchProviders.AvailableSearchProviders.Count > 1
        /// </summary>
        /// <returns></returns>
        //public string buttonSearchSplit_GetContent()
        //{
        //    log.Debug("in buttonSearchSplit_GetContent!");

        //    if (SearchProviders.AvailableSearchProviders.Count == 1
        //         && !SearchProviders.isGoogleDesktopSearchAvailable)
        //    {
        //        log.Debug(".. nothing to do");
        //        return null;
        //    }

        //    try
        //    {

        //        StringBuilder MyStringBuilder = new StringBuilder();


        //        for (int i = docState.index.Index + 1;
        //            ((i < dt.Rows.Count) && (i <= (docState.index.Index + DROPDOWN_MAX_ENTRIES))); i++)
        //        {

        //            MyStringBuilder.Append(@"<button id=""" + NEXT_PREFIX + i + @""" tag=""uri1"" label="""
        //                + dt.Rows[i].ItemArray[0] + @""" onAction=""buttonNextDoc_Click""  imageMso=""SignatureLineInsert"" />");
        //        }
        //        MyStringBuilder.Append(@"</menu>");
        //        return MyStringBuilder.ToString();
        //    }
        //    catch (Exception e)
        //    {
        //        log.Error(e.StackTrace);
        //        GlobalErrorHandler.HandleException(e);
        //        return null;
        //    }

        //}


        #endregion
    }
}
